#include "AC33Mxxx_conf.h"



// PCU
CSP_PCU_T		* const		PCU_A		= (CSP_PCU_T *) PCU_A_BASE_ADDRESS; 
CSP_PCU_T		* const		PCU_B		= (CSP_PCU_T *) PCU_B_BASE_ADDRESS; 
CSP_PCU_T		* const		PCU_C		= (CSP_PCU_T *) PCU_C_BASE_ADDRESS; 
CSP_PCU_T		* const		PCU_D		= (CSP_PCU_T *) PCU_D_BASE_ADDRESS; 



/**
***********************************************************************************************************
* @ Name : CSP_PCU_Init
*
* @ Parameter
*		pcu		= PCU_A, PCU_B, PCU_C, PCU_D
*
*
*
***********************************************************************************************************
*/
void CSP_PCU_Init (void)
{
	volatile UINT32		reg_val; 
	
	CSP_PCU_AccessEnable();

	//--------------------------------------------------------------------------------
	// Port A
	//
	//				PAMR		@ address = 0x4000_1000
	//				PACR		@ address = 0x4000_1004
	//
	//--------------------------------------------------------------------------------
	//				PA0			= PA0
	//				PA1			= PA1
	//				PA2			= PA2
	//				PA3			= PA3
	//
	//				PA4			= PA4
	//				PA5			= PA5
	//				PA6			= PA6
	//				PA7			= PA7
	//
	//				PA8			= PA8
	//				PA9			= PA9
	//				PA10		= PA10
	//				PA11		= PA11
	//
	//				PA12		= PA12
	//				PA13		= PA13
	//				PA14		= PA14
	//				PA15		= PA15
	//
	//--------------------------------------------------------------------------------
	reg_val = CSP_PCU_GET_PnMR(PCU_A); 
	reg_val &= 0x00000000; 						// All GPIO
	//reg_val += 0x00000000; 					// 
	CSP_PCU_SET_PnMR(PCU_A, reg_val); 


	reg_val = CSP_PCU_GET_PnCR(PCU_A); 
	//reg_val &= 0x00000000; 
	//reg_val += 0x00000000; 
	CSP_PCU_SET_PnCR(PCU_A, reg_val); 

	//--------------------------------------------------------------------------------
	// Port B
	//
	//				PBMR		@ address = 0x4000_1100
	//				PBCR		@ address = 0x4000_1104
	//
	//--------------------------------------------------------------------------------
	//
	//				PB0			= PWM0H0
	//				PB1			= PWM0L0
	//				PB2			= PWM0H1
	//				PB3			= PWM0L1
	//
	//				PB4			= PWM0H2
	//				PB5			= PWM0L2
	//				PB6			= EMG00
	//				PB7			= EMG01
	//
	//				PB8			= EMG10
	//				PB9			= EMG11
	//				PB10		= PWM1H0
	//				PB11		= PWM1L0
	//
	//				PB12		= PWM1H1
	//				PB13		= PWM1L1
	//				PB14		= PWM1H2
	//				PB15		= PWM1L2
	//
	//--------------------------------------------------------------------------------	
	CSP_PCU_SET_PnMR(PCU_B, 0x55555555); 		// 
	CSP_PCU_SET_PnCR(PCU_B, 0x000AA000); 		// EMG Inputs


	
	//--------------------------------------------------------------------------------
	// Port C
	//
	//				PCMR		@ address = 0x4000_1200
	//				PCCR		@ address = 0x4000_1204
	//
	//--------------------------------------------------------------------------------
	//
	//				PC0			= TCK/SWCLK
	//				PC1			= TMS/SWDIO
	//				PC2			= TDO/SWO
	//				PC3			= TDI
	//
	//				PC4			= nTRST
	//				PC5			= RXD1 
	//				PC6			= TXD1
	//				PC7			= SCL0
	//
	//				PC8			= SDA0
	//				PC9			= CLKO
	//				PC10		= nRESET
	//				PC11		= PC11
	//
	//				PC12		= XIN
	//				PC13		= XOUT
	//				PC14		= RXD0
	//				PC15		= TXD0
	//
	//--------------------------------------------------------------------------------		
	CSP_PCU_SET_PnMR(PCU_C, 0x55155555); 
	CSP_PCU_SET_PnCR(PCU_C, 0x2F214A8A); 


	
	//--------------------------------------------------------------------------------
	// Port D
	//
	//				PDMR		@ address = 0x4000_1300
	//				PDCR		@ address = 0x4000_1304
	//
	//--------------------------------------------------------------------------------
	//
	//				PD0			= 
	//				PD1			= 
	//				PD2			= 
	//				PD3			= 
	//
	//				PD4			= 
	//				PD5			= 
	//				PD6			= 
	//				PD7			= 
	//
	//				PD8			= 
	//				PD9			= 
	//				PD10		= 
	//				PD11		= 
	//
	//				PD12		= 
	//				PD13		= 
	//				PD14		= 
	//				PD15		= 
	//
	//--------------------------------------------------------------------------------		
	CSP_PCU_SET_PnMR(PCU_D, 0x00000000); 
	CSP_PCU_SET_PnCR(PCU_D, 0x00000000);	
	
	//CSP_PCU_AccessDisable();
	
}


/**
***********************************************************************************************************
* @ Name : CSP_PCU_ConfigureFunction
*
* @ Parameter
*		pcu		= PCU_A, PCU_B, PCU_C, PCU_D
*		pin_no	= PIN_0, PIN_1, PIN_2 , PIN_3 , PIN_4 , PIN_5 , PIN_6 , PIN_7 
*		          PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15 
*		func		
*
*
*
***********************************************************************************************************
*/
void CSP_PCU_ConfigureFunction (CSP_PCU_T * const pcu, UINT32 pin_no, UINT32 func)
{
	UINT32	pin_offset; 
	UINT32 	reg_val; 



	//------------------------------------------------------------------------------
	// pin_offset = pin_no * 2
	//------------------------------------------------------------------------------
	pin_offset = (pin_no << 1); 


	//------------------------------------------------------------------------------
	// PnMR
	//------------------------------------------------------------------------------
	reg_val = CSP_PCU_GET_PnMR(pcu); 
	reg_val &= ~(PnMR_FUNC_MASK << pin_offset); 
	reg_val |= func; 

	CSP_PCU_SET_PnMR(pcu, reg_val); 

}


/**
***********************************************************************************************************
* @ Name : CSP_PCU_Set_Direction_Type
*
* @ Parameter
*		pcu		= PCU_A, PCU_B, PCU_C, PCU_D
*		pin_no	= PIN_0, PIN_1, PIN_2 , PIN_3 , PIN_4 , PIN_5 , PIN_6 , PIN_7 
*		          PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15 
*		dir_type	= PnCR_OUTPUT_PUSH_PULL, PnCR_OUTPUT_OPEN_DRAIN, 
*				   PnCR_INPUT_LOGIC, PnCR_INPUT_ANALOG
*
*
***********************************************************************************************************
*/
void CSP_PCU_Set_Direction_Type (CSP_PCU_T * const pcu, UINT32 pin_no, UINT32 dir_type)
{

	UINT32	pin_offset; 
	UINT32 	reg_val; 


	//------------------------------------------------------------------------------
	// pin_offset = pin_no * 2
	//------------------------------------------------------------------------------
	pin_offset = (pin_no << 1); 


	//------------------------------------------------------------------------------
	// PnCR
	//------------------------------------------------------------------------------
	reg_val = CSP_PCU_GET_PnCR(pcu); 
	reg_val &= ~(PnCR_MASK << pin_offset); 
	reg_val |= ((dir_type & PnCR_MASK) << pin_offset); 

	CSP_PCU_SET_PnCR(pcu, reg_val); 

}


/**
***********************************************************************************************************
* @ Name : CSP_PCU_ConfigurePullup
*
* @ Parameter
*		pcu		= PCU_A, PCU_B, PCU_C, PCU_D
*		pin_no	= PIN_0, PIN_1, PIN_2 , PIN_3 , PIN_4 , PIN_5 , PIN_6 , PIN_7 
*		          PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15 
*		pullup	= PnPCR_PULLUP_DISABLE, PnPCR_PULLUP_ENABLE
*
*
***********************************************************************************************************
*/
void CSP_PCU_ConfigurePullup (CSP_PCU_T * const pcu, UINT32 pin_no, UINT32 pullup)
{
	UINT32	reg_val; 

	reg_val = CSP_PCU_GET_PnPCR(pcu); 
	reg_val &= ~(0x01<<pin_no); 

	if (pullup == PnPCR_PULLUP_ENABLE)
		reg_val |= (0x01<<pin_no); 

	CSP_PCU_SET_PnPCR(pcu, reg_val); 

}




/**
***********************************************************************************************************
* @ Name : CSP_PCU_ConfigureInterrupt
*
* @ Parameter
*		pcu		= PCU_A, PCU_B, PCU_C, PCU_D
*		pin_no	= PIN_0, PIN_1, PIN_2 , PIN_3 , PIN_4 , PIN_5 , PIN_6 , PIN_7 
*		          PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15 
*
*		intr_mask	= PCU_NO_INTR, 
*				  	   PCU_LOW_LEVEL_INTR, PCU_HIGH_LEVEL_INTR, 
*					   PCU_FALING_EDGE_INTR, PCU_RISING_EDGE_INTR, PCU_BOTH_FALLING_RISING_EDGE_INTR
*					
*		enable		= INTR_ENABLE, INTR_DISABLE
*
*
************************************************************************************************************
*/
void CSP_PCU_ConfigureInterrupt (CSP_PCU_T * const pcu, UINT32 pin_no, UINT32 intr_mask, UINT32 enable)
{

	UINT32		pin_offset; 
	UINT32		ier, icr; 
	UINT32		reg_val; 

	
	//------------------------------------------------------------------------------
	// pin_offset = pin_no * 2
	//------------------------------------------------------------------------------
	pin_offset = (pin_no << 1); 



	//------------------------------------------------------------------------------
	// disable interrupt
	//------------------------------------------------------------------------------
	ier = CSP_PCU_GET_PnIER(pcu); 
	icr = CSP_PCU_GET_PnICR(pcu); 

	ier &= ~(0x0003 << pin_offset); 
	icr &= ~(0x0003 << pin_offset); 
	
	CSP_PCU_SET_PnIER(pcu, ier); 
	CSP_PCU_SET_PnICR(pcu, icr); 
	


	//------------------------------------------------------------------------------
	// clear interrupt flag
	//------------------------------------------------------------------------------	
	reg_val = CSP_PCU_GET_PnISR(pcu); 
	reg_val &= (PnISR_MASK << pin_offset); 
	CSP_PCU_SET_PnISR(pcu, reg_val); 


	//------------------------------------------------------------------------------
	// enable interrupt
	//------------------------------------------------------------------------------
	if (enable == INTR_ENABLE)
	{
		ier |= ((intr_mask & 0x03) << pin_offset); 
		icr |= (((intr_mask & 0x30)>>4) << pin_offset); 

		CSP_PCU_SET_PnICR(pcu, icr);		
		CSP_PCU_SET_PnIER(pcu, ier); 
	
	}

}

void	CSP_PCU_AccessEnable(void)
{
	 CSP_PCU_SET_PORTEN(0x15); 
	 CSP_PCU_SET_PORTEN(0x51); 
}

void	CSP_PCU_AccessDisable(void)
{
	 CSP_PCU_SET_PORTEN(0); 
	 CSP_PCU_SET_PORTEN(0); 
}
